self.onmessage = function(event) {
  let message = event.data;

  if (message.type === 'draw') {
    let {data, config} = message;

    function drawShape(ctx, options, point, radius) {
      ctx.beginPath();
      ctx.arc(point.x, point.y, radius, 0, Math.PI * 2);

      if (options.fillOpacity !== 0) {
        ctx.fillStyle = options.fillColor;
        ctx.globalAlpha = options.fillOpacity;
        ctx.fill();
      }

      if (options.opacity !== 0) {
        ctx.lineWidth = options.weight;
        ctx.strokeStyle = options.color;
        ctx.globalAlpha = options.opacity || 1;
      }

      if (options.opacity === 0 && options.fillOpacity === 0) {
        ctx.strokeStyle = 'rgba(0,0,0,0)';
      }

      ctx.stroke();
    }

    function drawSector(ctx, options, point, radius) {
      ctx.beginPath();
      ctx.moveTo(point.x, point.y);
      let startAngle, endAngle;

      if (options.switch) {
        startAngle = (options.direction - options.angle / 2) * Math.PI / 180;
        endAngle = (options.direction + options.angle / 2) * Math.PI / 180;
      } else {
        startAngle = options.startAngle * Math.PI / 180;
        endAngle = options.endAngle * Math.PI / 180;
      }

      ctx.arc(point.x, point.y, radius, startAngle, endAngle, false);
      ctx.lineTo(point.x, point.y);
      ctx.closePath();

      if (options.fillOpacity !== 0) {
        ctx.fillStyle = options.fillColor;
        ctx.globalAlpha = options.fillOpacity;
        ctx.fill();
      }

      if (options.opacity !== 0) {
        ctx.lineWidth = options.weight;
        ctx.strokeStyle = options.color;
        ctx.globalAlpha = options.opacity || 1;
      }

      if (options.opacity === 0 && options.fillOpacity === 0) {
        ctx.strokeStyle = 'rgba(0,0,0,0)';
      }

      ctx.stroke();
    }

    function drawCanvas() {
      let _canvas = new OffscreenCanvas(config.width, config.height);
      let ctx = _canvas.getContext('2d');
      let batchSize = 500;
      let batchCount = Math.ceil(data.length / batchSize);
      // 开始时间
      const start = performance.now();
      for (let batch = 0; batch < batchCount; batch++) {
        let start = batch * batchSize;
        let end = Math.min(start + batchSize, data.length);

        for (let i = start; i < end; i++) {
          let circles = data[i];
          let options = circles;
          let {sector, point} = circles;
          if (sector) {
            drawSector(ctx, options, point, circles._radius);
          } else {
            drawShape(ctx, options, point, circles._radius);
          }
        }
      }
      const end = performance.now();
      const executionTime = end - start;
      console.log(`time: ${executionTime} ms`);
      return _canvas;
    }

    let _newCanvas = drawCanvas();
    let imageBitmap = _newCanvas.transferToImageBitmap();
    self.postMessage(imageBitmap, [imageBitmap]);
  }
};